package com.zoagroup.funzy.entity;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import com.zoagroup.funzy.entity.enums.Profile;

/**
 * The persistent class for the user database table.
 * 
 */
@Entity
public class User implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="id_user", unique=true, nullable=false)
	private Integer idUser;

	private Integer credit;

	@Column(name="facebook_key")
	private String facebookKey;

	@Column(name="id_facebook")
	private String idFacebook;
	
	@Column(name="latitude")
	private String latitude;
	
	@Column(name="longitude")
	private String longitude;

	@Column(name="name")
	private String name;

	@Column(name="photo")
	private String photo;
	
	@Enumerated(EnumType.STRING)
	@Column(name="profile")
	private Profile profile;

	@Column(name="username")
	private String username;

	@Column(name="userpass")
	private String userpass;

	//bi-directional many-to-one association to Activity
	@OneToMany(mappedBy="user",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	private List<Activity> myActivities;

	//bi-directional many-to-many association to User
	@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	@JoinTable(name="following"
		, joinColumns={@JoinColumn(name="id_user")}
		, inverseJoinColumns={@JoinColumn(name="id_user_following")})
	private List<User> acompanho;

	//bi-directional many-to-many association to User
	@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	@JoinTable(name="following"
			, joinColumns={@JoinColumn(name="id_user_following")}
			, inverseJoinColumns={@JoinColumn(name="id_user")})
	private List<User> meAcompanham;

	//bi-directional many-to-one association to Message
	@OneToMany(mappedBy="user",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	private List<Message> messages;

	//bi-directional many-to-one association to Product
	@OneToMany(mappedBy="user",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	private List<Product> products;

	//bi-directional many-to-one association to TypeUser
	@ManyToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="type_user")
	private TypeUser typeUserBean;

	//bi-directional many-to-many association to Activity
	@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	@JoinTable(name="user_activity"
		, joinColumns={@JoinColumn(name="id_user")}
		, inverseJoinColumns={@JoinColumn(name="id_activity")})
	private List<Activity> participatingActivities;

	//bi-directional many-to-many association to Group
	@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	@JoinTable(name="user_group"
		, joinColumns={@JoinColumn(name="id_user")}
		, inverseJoinColumns={@JoinColumn(name="id_group")})
	private List<Group> groups;
	
	@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	@JoinTable(name="user_achievement"
		, joinColumns={@JoinColumn(name="id_user")}
		, inverseJoinColumns={@JoinColumn(name="id_achievement")})
	private List<Achievement> achievements;
	
	@OneToMany(mappedBy="user", cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	private List<UserMessage> messagesToMe;
	
	@OneToMany(mappedBy="user", cascade=CascadeType.ALL,fetch=FetchType.LAZY)
	private List<StageResult> stageResults;
	
	public List<Achievement> getAchievements() {
		return achievements;
	}

	public void setAchievements(List<Achievement> achievements) {
		this.achievements = achievements;
	}

	public User() {
	}

	public Integer getIdUser() {
		return this.idUser;
	}

	public void setIdUser(Integer idUser) {
		this.idUser = idUser;
	}

	public Integer getCredit() {
		return this.credit;
	}

	public void setCredit(Integer credit) {
		this.credit = credit;
	}

	public String getFacebookKey() {
		return this.facebookKey;
	}

	public void setFacebookKey(String facebookKey) {
		this.facebookKey = facebookKey;
	}

	public String getIdFacebook() {
		return this.idFacebook;
	}

	public void setIdFacebook(String idFacebook) {
		this.idFacebook = idFacebook;
	}

	public String getLatitude() {
		return this.latitude;
	}

	public void setLatitude(String latitude) {
		this.latitude = latitude;
	}

	public String getLongitude() {
		return this.longitude;
	}

	public void setLongitude(String longitude) {
		this.longitude = longitude;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPhoto() {
		return this.photo;
	}

	public void setPhoto(String photo) {
		this.photo = photo;
	}

	public Profile getProfile() {
		return this.profile;
	}

	public void setProfile(Profile profile) {
		this.profile = profile;
	}

	public String getUsername() {
		return this.username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getUserpass() {
		return this.userpass;
	}

	public void setUserpass(String userpass) {
		this.userpass = userpass;
	}

	public List<Activity> getMyActivities() {
		return this.myActivities;
	}

	public void setMyActivities(List<Activity> myActivities) {
		this.myActivities = myActivities;
	}

	public Activity addMyActivity(Activity myActivity) {
		if(myActivities == null) {
			myActivities = new LinkedList<Activity>();
		}
		getMyActivities().add(myActivity);
		myActivity.setUser(this);

		return myActivity;
	}

	public Activity removeMyActivity(Activity myActivity) {
		if(myActivities == null) {
			myActivities = new LinkedList<Activity>();
		}
		getMyActivities().remove(myActivity);
		myActivity.setUser(null);

		return myActivity;
	}

	public List<User> getAcompanho() {
		return this.acompanho;
	}

	public void setAcompanho(List<User> acompanho) {
		this.acompanho = acompanho;
	}

	public List<User> getMeAcompanham() {
		return this.meAcompanham;
	}

	public void setMeAcompanham(List<User> meAcompanham) {
		this.meAcompanham = meAcompanham;
	}

	public List<Message> getMessages() {
		return this.messages;
	}

	public void setMessages(List<Message> messages) {
		this.messages = messages;
	}

	public Message addMessage(Message message) {
		if (this.messages == null) {
			this.messages = new LinkedList<Message>();
		}
		getMessages().add(message);
		message.setUser(this);

		return message;
	}

	public Message removeMessage(Message message) {
		if (this.messages == null) {
			this.messages = new LinkedList<Message>();
		}
		getMessages().remove(message);
		message.setUser(null);

		return message;
	}

	public List<Product> getProducts() {
		return this.products;
	}

	public void setProducts(List<Product> products) {
		this.products = products;
	}

	public Product addProduct(Product product) {
		if(this.products == null) {
			this.products = new LinkedList<Product>();
		}
		
		getProducts().add(product);
		product.setUser(this);

		return product;
	}

	public Product removeProduct(Product product) {
		if(this.products == null) {
			this.products = new LinkedList<Product>();
		}
		getProducts().remove(product);
		product.setUser(null);

		return product;
	}

	public TypeUser getTypeUserBean() {
		return this.typeUserBean;
	}

	public void setTypeUserBean(TypeUser typeUserBean) {
		this.typeUserBean = typeUserBean;
	}

	public List<Activity> getParticipatingActivities() {
		return this.participatingActivities;
	}

	public void setParticipatingActivities(List<Activity> participatingActivities) {
		this.participatingActivities = participatingActivities;
	}

	public List<Group> getGroups() {
		return this.groups;
	}

	public void setGroups(List<Group> groups) {
		this.groups = groups;
	}
	
	public List<StageResult> getStageResults() {
		return this.stageResults;
	}

	public void setStageResults(List<StageResult> stageResults) {
		this.stageResults = stageResults;
	}

	public StageResult addStageResult(StageResult stageResult) {
		if(this.stageResults == null) {
			this.stageResults = new LinkedList<StageResult>();
		}
		getStageResults().add(stageResult);
		stageResult.setUser(this);

		return stageResult;
	}

	public StageResult removeStageResult(StageResult stageResult) {
		if(this.stageResults == null) {
			this.stageResults = new LinkedList<StageResult>();
		}
		getStageResults().remove(stageResult);
		stageResult.setUser(null);

		return stageResult;
	}

	public List<UserMessage> getMessagesToMe() {
		return messagesToMe;
	}

	public void setMessagesToMe(List<UserMessage> messagesToMe) {
		this.messagesToMe = messagesToMe;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((facebookKey == null) ? 0 : facebookKey.hashCode());
		result = prime * result
				+ ((idFacebook == null) ? 0 : idFacebook.hashCode());
		result = prime * result + ((idUser == null) ? 0 : idUser.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (facebookKey == null) {
			if (other.facebookKey != null)
				return false;
		} else if (!facebookKey.equals(other.facebookKey))
			return false;
		if (idFacebook == null) {
			if (other.idFacebook != null)
				return false;
		} else if (!idFacebook.equals(other.idFacebook))
			return false;
		if (idUser == null) {
			if (other.idUser != null)
				return false;
		} else if (!idUser.equals(other.idUser))
			return false;
		return true;
	}
}